/*
 * Copyright Hundsun Technologies Inc. All Rights Reserved.
 */

package state

import (
	"github.com/golang/protobuf/proto"
	"hundsun.com/hsl/hschain/common/types"
	pbcom "hundsun.com/hsl/hschain/protos/common"
	pbevm "hundsun.com/hsl/hschain/protos/evm"
	"hundsun.com/hsl/hschain/store/db"
)

const (
	// NamespaceEvmStateData evm 状态数据空间
	NamespaceEvmStateData = "ns.evm.std" + db.PrefixSeparator
)

// genEvmStateDataKey 获取状态数据key
func genEvmStateDataKey(address, key []byte) []byte {
	rkey := append([]byte{}, []byte(NamespaceEvmStateData)...)
	rkey = append(rkey, address...)
	rkey = append(rkey, key...)
	return rkey
}

// EVMContractInfoDB EVMContractInfo存储对象
type EVMContractInfoDB struct {
	get db.DatabaseGet
}

// NewEVMContractInfoDB new EVMContractInfoDB
func NewEVMContractInfoDB(get db.DatabaseGet) *EVMContractInfoDB {
	return &EVMContractInfoDB{get: get}
}

// GetEVMContractInfo get EVMContractInfo from address
func (c *EVMContractInfoDB) GetEVMContractInfo(address []byte) (*pbevm.EVMContractInfo, error) {
	if c.get == nil {
		return nil, types.ErrNotFound
	}
	v, err := c.get.Get(genEvmContractInfoKey(address))
	if err != nil {
		return nil, err
	}
	info := &pbevm.EVMContractInfo{}
	err = proto.Unmarshal(v, info)
	if err != nil {
		return nil, err
	}
	return info, nil
}

// EVMContractInfoDBKV from EVMContractInfoDB to kv
func EVMContractInfoDBKV(info *pbevm.EVMContractInfo, address []byte) (*pbcom.KeyValue, error) {
	kv := &pbcom.KeyValue{}
	kv.Key = genEvmContractInfoKey(address)
	v, err := proto.Marshal(info)
	if err != nil {
		return nil, err
	}
	kv.Value = v
	return kv, nil
}

func genEvmContractInfoKey(address []byte) []byte {
	rkey := append([]byte{}, []byte(NamespaceEvmStateData+"info:")...)
	rkey = append(rkey, address...)
	return rkey
}
